package com.kelvin.oocl.testTransaction.proxy;

import com.kelvin.oocl.testTransaction.annotation.IsStartTransaction;
import com.kelvin.oocl.testTransaction.exception.DBOperationException;
import com.kelvin.oocl.testTransaction.tool.DBUtils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

public class ServiceTransactionProxy implements InvocationHandler{
	private Object target;
	
	public ServiceTransactionProxy(Object target) {
		super();
		this.target = target;
	}
	
	public Object createProxy(){
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
		if(!method.isAnnotationPresent(IsStartTransaction.class)){ //不开启事务
			System.out.println("Do not start transaction");
			return method.invoke(target, args);
		}
		Connection connection = null;
		Object returnValue = null;
		try {
			connection = DBUtils.getConnection();
			connection.setAutoCommit(false);
			System.out.println("start transaction");
			returnValue = method.invoke(target, args);
			connection.commit();
			System.out.println("commit transaction");
		} catch (Exception e) {
			System.out.println("rollback transaction");
			connection.rollback();
			e.printStackTrace();
			throw new DBOperationException("service operation failed.");
		} finally {
			DBUtils.close(null, connection);
		}
		return returnValue;
	}

}
